import { IsString, IsOptional, IsBoolean, IsEmail, Length, IsNotEmpty, ValidateIf, IsInt, IsNumber, IsArray, ArrayMinSize } from 'class-validator';
import { PaginationDto } from '@dtos/pagination.dto';

/**
 * 创建用户 DTO
 */
export class CreateUserDto {
  @IsString({ message: '姓名必须是字符串' })
  @IsNotEmpty({ message: '姓名不能为空' })
  @Length(1, 50, { message: '姓名长度为 1-50 位' })
  name: string;

  @IsString({ message: '用户名必须是字符串' })
  @IsNotEmpty({ message: '用户名不能为空' })
  @Length(8, 16, { message: '用户名长度 8-16 位' })
  username: string;

  @IsString({ message: '密码必须是字符串' })
  @IsOptional()
  @Length(8, 16, { message: '密码长度为 8-16 位' })
  password?: string;

  @IsInt({ message: '部门 ID 必须是整数' })
  @IsOptional()
  departmentId?: number;

  @IsBoolean({ message: '状态必须是布尔值' })
  @IsOptional()
  status?: boolean;

  @IsEmail({}, { message: '邮箱格式不正确' })
  @IsOptional()
  @Length(1, 50, { message: '邮箱长度为 1-50 位' })
  email?: string;

  @IsString({ message: '手机号必须是字符串' })
  @IsOptional()
  @Length(11, 11, { message: '手机号长度为 11 位' })
  phone?: string;

  @IsString({ message: '备注必须是字符串' })
  @IsOptional()
  @Length(1, 100, { message: '备注长度为 1-100 位' })
  remark?: string;

  @IsOptional()
  @IsArray({ message: '角色列表必须是数组' })
  @IsInt({ each: true, message: '角色 ID 必须是整数' })
  @ArrayMinSize(0)
  roleIds?: number[];
}

/**
 * 更新自身信息 DTO
 */
export class UpdateMyselfDto {
  @IsString({ message: '姓名必须是字符串' })
  @Length(1, 50, { message: '姓名长度为 1-50 位' })
  name: string;

  @IsEmail({}, { message: '邮箱格式不正确' })
  @Length(1, 50, { message: '邮箱长度为 1-50 位' })
  email: string;

  @IsString({ message: '手机号必须是字符串' })
  @Length(11, 11, { message: '手机号长度为 11 位' })
  phone: string;
}

/**
 * 更新用户 DTO
 */
export class UpdateUserDto extends UpdateMyselfDto {
  @IsInt({ message: '部门 ID 必须是整数' })
  @IsOptional()
  departmentId?: number;

  @IsArray({ message: '角色列表必须是数组' })
  @IsOptional()
  @IsString({ each: true, message: '角色编号必须为字符串' })
  roles?: string[];

  @IsBoolean({ message: '状态必须是布尔值' })
  @IsOptional()
  status?: boolean;

  @IsString({ message: '备注必须是字符串' })
  @IsOptional()
  @Length(1, 100, { message: '备注长度为 1-100 位' })
  remark?: string;
}

/**
 * 登录用户 DTO
 */
export class LoginUserDto {
  @IsOptional()
  @IsString({ message: '用户名必须为字符串' })
  @IsNotEmpty({ message: '用户名不能为空' })
  @Length(8, 16, { message: '用户名长度 8-16 位' })
  // 仅在 email 未填时生效
  @ValidateIf(o => !o.email)
  username?: string;

  @IsOptional()
  @IsString()
  @IsNotEmpty()
  @Length(1, 50)
  @ValidateIf(o => !o.username)
  email?: string;

  @IsString({ message: '密码必须为字符串' })
  @IsNotEmpty({ message: '密码不能为空' })
  @Length(8, 16, { message: '密码长度 8-16 位' })
  password!: string;
}

/**
 * 修改密码 DTO
 */
export class ResetPasswordDto {
  @IsString({ message: '旧密码必须是字符串' })
  @IsNotEmpty({ message: '旧密码不能为空' })
  @Length(8, 16, { message: '旧密码长度为 8-16 位' })
  old_password: string;

  @IsString({ message: '新密码必须是字符串' })
  @IsNotEmpty({ message: '新密码不能为空' })
  @Length(8, 16, { message: '新密码长度为 8-16 位' })
  new_password: string;
}

/**
 * 用户分页查询 DTO
 */
export class UserPageDto extends PaginationDto {
  @IsString({ message: '用户名必须是字符串' })
  @IsOptional()
  username?: string;

  @IsString({ message: '姓名必须是字符串' })
  @IsOptional()
  name?: string;

  @IsNumber({}, { message: '部门 ID 必须是数字' })
  @IsOptional()
  departmentId?: number;
}
